package com.yanqu.road.logic.activity.fivehero.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.fivehero.config.FiveHeroCityConfig;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class FiveHeroMapLogic {

    /**
     * 地图数据，找客户端要
     */
    public static String MAP_PARAM = "{\"103\":[1003,132,134,133],\"105\":[1003,134,135],\"131\":[132,160,162,161],\"132\":[103,131,133,162],\"133\":[103,132,134,162,164],\"134\":[1003,103,105,133,135,164],\"135\":[105,134,164,166,165],\"138\":[139,168],\"139\":[138,168,2001],\"141\":[2001,172,171],\"158\":[2002,159,188],\"159\":[2002,158,160,188,190,189],\"160\":[2002,131,159,161,190],\"161\":[131,160,162,190,192,191],\"162\":[132,131,133,161,192],\"164\":[134,133,135,165],\"165\":[135,164,166,196,2003],\"166\":[135,165,167,196],\"167\":[166,168,196,198,197],\"168\":[138,139,167,198],\"171\":[141,2001,172,202,201],\"172\":[141,171,202],\"188\":[158,159,189],\"189\":[159,188,190,220],\"190\":[160,159,161,189,191,220],\"191\":[161,190,192,220,222,221],\"192\":[162,161,191,222],\"196\":[166,165,167,2003,197,226],\"197\":[167,196,198,226,227],\"198\":[168,167,197],\"201\":[171,202,230,232,231],\"202\":[172,171,201,232],\"205\":[234,236,235],\"215\":[1002,246,245],\"220\":[190,189,191,221],\"221\":[191,220,222,252,2004],\"222\":[192,191,221,223,252],\"223\":[222,224,252,254],\"224\":[2003,223,225,254],\"225\":[2003,224,226,254,256,255],\"226\":[196,2003,197,225,227,256],\"227\":[197,226,256,257],\"230\":[201,231,260],\"231\":[201,230,232,260],\"232\":[202,201,231,233],\"233\":[232,234,264,263],\"234\":[205,233,235,264],\"235\":[205,234,236,264,1005,265],\"236\":[205,235,237,1005],\"237\":[236,1005],\"245\":[215,1002,246,274,276,275],\"246\":[215,245,247,276],\"247\":[246,276,278,277],\"252\":[222,221,223,2004],\"254\":[224,223,225,255,284],\"255\":[225,254,256,284,286,3003],\"256\":[226,225,227,255,257,286],\"257\":[227,256,286,288,287],\"260\":[230,231,2011,290],\"263\":[233,264,293],\"264\":[234,233,235,263,265],\"265\":[235,264,1005,295],\"273\":[1002,274,304],\"274\":[1002,245,273,275,304],\"275\":[245,274,276,304,2005,305],\"276\":[246,245,247,275,277,2005],\"277\":[247,276,278,2005],\"278\":[247,277,279],\"279\":[278,280,310,309],\"280\":[2004,279,281,310],\"281\":[2004,280,310,312,311],\"283\":[284,312,3003],\"284\":[254,255,283,3003],\"286\":[256,255,257,3003,287],\"287\":[257,286,288,3003,318],\"288\":[257,2011,287,318],\"290\":[260,2011,320],\"293\":[263,2012,324,323],\"295\":[265,1005,324,326,325],\"304\":[274,273,275,305,334],\"305\":[275,304,2005,334,335],\"309\":[279,310,338,340,339],\"310\":[280,279,281,309,311,340],\"311\":[281,310,312,340,3004],\"312\":[281,283,311,3004],\"318\":[288,287,319,3001],\"319\":[318,320,3001,350],\"320\":[290,319,321,350],\"321\":[320,2012,350],\"323\":[293,2012,324,354,353],\"324\":[293,295,323,325,354],\"325\":[295,324,326,354],\"326\":[1005,295,325],\"333\":[334,364,363],\"334\":[304,305,333,335,364],\"335\":[305,334,364,366,365],\"337\":[338,366,368,2006],\"338\":[309,337,339,368],\"339\":[309,338,340,368,370,369],\"340\":[310,309,311,339,3004,370],\"345\":[3003,374,376,4001],\"350\":[320,319,321,3001,380],\"353\":[323,354,382],\"354\":[324,323,325,353],\"363\":[333,364,394,393],\"364\":[334,333,335,363,365,394],\"365\":[335,364,366,394],\"366\":[335,337,365,2006],\"368\":[338,337,339,2006,369,398],\"369\":[339,368,370,398,400,399],\"370\":[340,339,3004,369,400],\"373\":[3004,374,4001,403],\"374\":[345,373,4001],\"376\":[345,4001,377],\"377\":[376,3001,4001,407],\"380\":[350,3001,381,410],\"381\":[380,382,410,412,2013],\"382\":[353,381,412],\"393\":[363,394,424,423],\"394\":[364,363,365,393,424],\"398\":[368,2006,369,399,428],\"399\":[369,398,400,428,430,429],\"400\":[370,369,3004,399,430],\"403\":[373,4001,433],\"407\":[377,4001,437],\"410\":[380,3001,381,2013,440],\"412\":[382,381,2013,442],\"423\":[393,424,454],\"424\":[394,393,423,425,454],\"425\":[424,454,456,2007],\"427\":[428,456,457],\"428\":[398,399,427,429],\"429\":[399,428,430,460],\"430\":[400,399,429,3002,460],\"433\":[403,4001,3002,464],\"437\":[407,4001,466,3005],\"440\":[410,2013,3005,441,470],\"441\":[2013,440,442,470,472,471],\"442\":[412,2013,441,443,472],\"443\":[442,444,472,474],\"444\":[443,445,474],\"445\":[444,474,476,475],\"454\":[424,423,425,2007],\"456\":[425,427,2007,457,486],\"457\":[427,456,486,487],\"460\":[430,429,3002,490],\"464\":[4001,433,465],\"465\":[4001,464,466],\"466\":[4001,437,465],\"470\":[440,3005,441,471,500],\"471\":[441,470,472,500,502],\"472\":[442,441,443,471,502],\"474\":[444,443,445,475],\"475\":[445,474,476,506,2015],\"476\":[445,475,506],\"486\":[456,2007,457,487],\"487\":[457,486,518,517],\"489\":[490,518,520,2008],\"490\":[460,3002,489,491,520],\"491\":[3002,490,520,522,521],\"499\":[3005,500,528,529],\"500\":[470,3005,471,499],\"502\":[472,471,503,532],\"503\":[502,532,534,533],\"506\":[476,475,2015],\"517\":[487,518,548],\"518\":[487,489,517,2008,548],\"520\":[490,489,491,2008,521],\"521\":[491,520,522,551],\"522\":[3002,491,521,523],\"523\":[522,554],\"527\":[528,556,558,557],\"528\":[3005,499,527,529,558],\"529\":[499,528,558,560],\"532\":[502,503,2014,533,562],\"533\":[503,532,534,562,563],\"534\":[503,2015,533],\"548\":[518,517,2008,578],\"551\":[521,2009,581],\"554\":[523,555],\"555\":[554,556,585],\"556\":[527,555,557],\"557\":[527,556,558,587],\"558\":[528,527,529,557],\"560\":[529,2014,590],\"562\":[532,2014,533,563,592],\"563\":[533,562,592,594,593],\"577\":[578,606,608,607],\"578\":[548,577,579,608],\"579\":[578,608,610,609],\"581\":[551,2009,610,612,611],\"585\":[555,614,2010,615],\"587\":[557,2010,618,617],\"590\":[560,620],\"592\":[562,563,593,622],\"593\":[563,592,594,622,624,623],\"594\":[563,593,624],\"605\":[606,636],\"606\":[577,605,607,636],\"607\":[577,606,608,636,1001],\"608\":[578,577,579,607,609,1001],\"609\":[579,608,610,1001,640],\"610\":[579,581,609,611,640],\"611\":[581,610,612,640,642],\"612\":[2009,581,611,613,642],\"613\":[612,614,642],\"614\":[585,613,615],\"615\":[585,614,2010],\"617\":[587,2010,618],\"618\":[587,617,619],\"619\":[618,620,650],\"620\":[590,619,621,650],\"621\":[620,622,650,652],\"622\":[592,593,621,623,652],\"623\":[593,622,624,652,1004],\"624\":[594,593,623,625,1004],\"625\":[624,1004],\"636\":[606,605,607,1001],\"640\":[610,609,611,1001],\"642\":[612,611,613],\"650\":[620,619,621],\"652\":[622,621,623,1004],\"1001\":[607,636,608,609,640],\"1002\":[215,274,273,245],\"1003\":[103,105,134],\"1004\":[623,652,624,625],\"1005\":[236,235,237,265,295,326],\"2001\":[139,141,171],\"2002\":[158,160,159],\"2003\":[165,196,224,226,225],\"2004\":[221,252,280,281],\"2005\":[276,275,277,305],\"2006\":[337,366,368,398],\"2007\":[425,454,456,486],\"2008\":[489,518,520,548],\"2009\":[551,581,612],\"2010\":[585,587,615,617],\"2011\":[260,288,290],\"2012\":[293,321,323],\"2013\":[381,410,412,440,442,441],\"2014\":[532,560,562],\"2015\":[475,506,534],\"3001\":[318,319,350,380,377,410],\"3002\":[430,460,490,491,433,522],\"3003\":[255,284,286,283,345,287],\"3004\":[311,340,370,312,400,373],\"3005\":[440,470,437,500,499,528],\"4001\":[345,374,376,373,403,377,407,433,464,466,465,437]}";

    public static Map<Integer,List<Integer>> mapLinkMap = new ConcurrentHashMap<>();

    //每一座城距离阵营主城距离
    public static Map<Integer,Map<Integer,Integer>> distanceMap = new ConcurrentHashMap<>();
    // =============================

    private static void initMap(){
        synchronized (mapLinkMap){
            if(mapLinkMap.size() == 0){
                String mapParam = MAP_PARAM;
                Map<Integer, List<Integer>> listMap = new ConcurrentHashMap<>();
                JSONObject jsonObject = JSONObject.parseObject(mapParam);
                for(String cityIdStr : jsonObject.keySet()){
                    int cityId = Integer.valueOf(cityIdStr);
                    JSONArray cityLink = jsonObject.getJSONArray(cityIdStr);
                    List<Integer> cityLinkList = new ArrayList<>();
                    for (Object o : cityLink){
                        String s = String.valueOf(o);
                        cityLinkList.add(Integer.valueOf(s));
                    }
                    listMap.put(cityId,cityLinkList);
                }
                mapLinkMap = listMap;
            }
        }


    }
    /**
     * 生成地图
     *
     * @return 地点，相邻地点List
     */
    public static Map<Integer, List<Integer>> getCityConnectMapConfig() {
        if(mapLinkMap.size() == 0){
            initMap();
        }

        return mapLinkMap;
    }

    public static Map<Integer,Map<Integer,Integer>> getCityDistanceMap(Map<Integer, FiveHeroCityConfig> cityConfigMap) {
        if(distanceMap.size() == 0){
            long startTime = System.currentTimeMillis();
//            System.err.println("开始跑距离");
            initDistanceMap(cityConfigMap);
            int i = 666;
            while (distanceMap.containsKey(-998) && i > 0){
                initDistanceMap(cityConfigMap);
                i--;
            }
//            long endTime = System.currentTimeMillis();
//            System.err.println("跑了" + (endTime - startTime) +"毫秒,i={}" + i);
//            System.err.println(JSON.toJSONString(distanceMap));
        }
//        distanceMap.clear();
//        initDistanceMap(cityConfigMap);

        return distanceMap;
    }

    /**
     * 生成mapDistanceMap
     */
    public static void initDistanceMap(Map<Integer, FiveHeroCityConfig> cityConfigMap) {
        synchronized (distanceMap){
            distanceMap.remove(-998);
            Map<Integer,Map<Integer,Integer>> tempDistanceMap = distanceMap;
            //对应阵营的主城id
            Map<Integer,Integer> campMainCityIdMap = new ConcurrentHashMap<>();
            for(FiveHeroCityConfig cityConfig : cityConfigMap.values()){
                if(cityConfig.getInitialCamp() != 0){
                    campMainCityIdMap.put(cityConfig.getInitialCamp(),cityConfig.getId());
                }
            }
            Map<Integer, List<Integer>> linkMap = getCityConnectMapConfig();
            for(int campId : campMainCityIdMap.keySet()){
                int cityId = campMainCityIdMap.get(campId);
                if(!tempDistanceMap.containsKey(cityId)){
                    tempDistanceMap.put(cityId,new ConcurrentHashMap<>());
                }
                tempDistanceMap.get(cityId).put(campId,0);
                List<Integer> linkCityList = linkMap.get(cityId);
                for(int linkCityId : linkCityList){
                    List<Integer> cityList = new ArrayList<>();
                    cityList.add(cityId);
                    outMainCity(campId,linkCityId,tempDistanceMap,cityList);
                }
            }
            distanceMap = tempDistanceMap;
        }
    }

    //从主城开始向外一直记录距离，记录完所有城池
    private static void outMainCity(int campId,int cityId,Map<Integer,Map<Integer,Integer>> tempDistanceMap,List<Integer> cityList){
        if(cityList.contains(cityId)){
            return;
        }else{
            cityList.add(cityId);
        }
        Map<Integer, List<Integer>> linkMap = getCityConnectMapConfig();
        if(!tempDistanceMap.containsKey(cityId)){
            tempDistanceMap.put(cityId,new ConcurrentHashMap<>());
        }
        List<Integer> linkCityList = linkMap.get(cityId);
        int minDistance = Integer.MAX_VALUE;
        for(int linkCityId : linkCityList){
            if(tempDistanceMap.containsKey(linkCityId) && tempDistanceMap.get(linkCityId).containsKey(campId)){
                int distance = tempDistanceMap.get(linkCityId).get(campId);
                if(distance < minDistance){
                    minDistance = distance;
                }
            }
        }
        if( tempDistanceMap.get(cityId).getOrDefault(campId,0) != minDistance + 1){
            distanceMap.put(-998,new ConcurrentHashMap<>());
        }
        tempDistanceMap.get(cityId).put(campId,minDistance + 1);
        for(int linkCityId : linkCityList){
            outMainCity(campId,linkCityId,tempDistanceMap,cityList);
        }
    }

    // =============================
}
